Implement a `plugin` flag for targets
authorAlex Crichton <alex@alexcrichton.com>
Fri, 11 Jul 2014 01:26:30 +0000 (18:26 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 11 Jul 2014 01:26:30 +0000 (18:26 -0700)
If `plugin = true` is specified, then the target is considered a compiler plugin
which implies two separate properties:

* The library must be compiled as a dylib
* The library must be compiled for the host architecture

src/cargo/core/manifest.rs
src/cargo/ops/cargo_rustc.rs
src/cargo/util/toml.rs

index 724f5216ea8afc9292cf284daf4d0bfe57ae5060..981547116941c8127d9c2e18c4ed712166ca11f0 100644 (file)
@@ -107,6 +107,7 @@ pub struct Profile {
     debug: bool,
     test: bool,
     dest: Option<String>,
+    plugin: bool,
 }
 
 impl Profile {
@@ -116,7 +117,8 @@ impl Profile {
             opt_level: 0,
             debug: true,
             test: false, // whether or not to pass --test
-            dest: None
+            dest: None,
+            plugin: false,
         }
     }
 
@@ -126,7 +128,8 @@ impl Profile {
             opt_level: 0,
             debug: true,
             test: true, // whether or not to pass --test
-            dest: Some("test".to_string())
+            dest: Some("test".to_string()),
+            plugin: false,
         }
     }
 
@@ -136,7 +139,8 @@ impl Profile {
             opt_level: 3,
             debug: false,
             test: true, // whether or not to pass --test
-            dest: Some("bench".to_string())
+            dest: Some("bench".to_string()),
+            plugin: false,
         }
     }
 
@@ -146,7 +150,8 @@ impl Profile {
             opt_level: 3,
             debug: false,
             test: false, // whether or not to pass --test
-            dest: Some("release".to_string())
+            dest: Some("release".to_string()),
+            plugin: false,
         }
     }
 
@@ -158,6 +163,10 @@ impl Profile {
         self.test
     }
 
+    pub fn is_plugin(&self) -> bool {
+        self.plugin
+    }
+
     pub fn get_opt_level(&self) -> uint {
         self.opt_level
     }
@@ -188,6 +197,11 @@ impl Profile {
         self.test = test;
         self
     }
+
+    pub fn plugin(mut self, plugin: bool) -> Profile {
+        self.plugin = plugin;
+        self
+    }
 }
 
 #[deriving(Clone, Hash, PartialEq)]
@@ -196,7 +210,7 @@ pub struct Target {
     name: String,
     src_path: Path,
     profile: Profile,
-    metadata: Option<Metadata>
+    metadata: Option<Metadata>,
 }
 
 #[deriving(Encodable)]
index 378efd9027a39e9bf8cc3cb44be952125eaa43bb..6f5acc64620cffe5ce2bbb7fcc7036ac6e8a1e3e 100644 (file)
@@ -330,11 +330,11 @@ fn build_base_args(into: &mut Args,
     }
 
     match cx.config.target() {
-        Some(target) => {
+        Some(target) if !profile.is_plugin() => {
             into.push("--target".to_string());
             into.push(target.to_string());
         }
-        None => {}
+        _ => {}
     }
 }
 
index 854609c2fa8e05c25039ddf6e6f4acd79e57935e..232cf0a0e5dbb7b13dfe65fc3ee45e5fd07b4f33 100644 (file)
@@ -5,7 +5,7 @@ use std::io::fs;
 use toml;
 
 use core::{SourceId, GitKind};
-use core::manifest::{LibKind, Lib, Profile};
+use core::manifest::{LibKind, Lib, Dylib, Profile};
 use core::{Summary, Manifest, Target, Dependency, PackageId};
 use core::package_id::Metadata;
 use core::source::Location;
@@ -201,7 +201,8 @@ fn inferred_lib_target(name: &str, layout: &Layout) -> Option<Vec<TomlTarget>> {
             name: name.to_string(),
             crate_type: None,
             path: Some(lib.display().to_string()),
-            test: None
+            test: None,
+            plugin: None,
         }]
     })
 }
@@ -219,7 +220,8 @@ fn inferred_bin_targets(name: &str, layout: &Layout) -> Option<Vec<TomlTarget>>
                 name: name,
                 crate_type: None,
                 path: Some(bin.display().to_string()),
-                test: None
+                test: None,
+                plugin: None,
             }
         })
     }).collect())
@@ -253,7 +255,8 @@ impl TomlManifest {
                         name: t.name.clone(),
                         crate_type: t.crate_type.clone(),
                         path: layout.lib.as_ref().map(|p| p.display().to_string()),
-                        test: t.test
+                        test: t.test,
+                        plugin: t.plugin,
                     }
                 } else {
                     t.clone()
@@ -272,7 +275,8 @@ impl TomlManifest {
                         name: t.name.clone(),
                         crate_type: t.crate_type.clone(),
                         path: bin.as_ref().map(|p| p.display().to_string()),
-                        test: t.test
+                        test: t.test,
+                        plugin: None,
                     }
                 } else {
                     t.clone()
@@ -376,7 +380,8 @@ struct TomlTarget {
     name: String,
     crate_type: Option<Vec<String>>,
     path: Option<String>,
-    test: Option<bool>
+    test: Option<bool>,
+    plugin: Option<bool>,
 }
 
 fn normalize(lib: Option<&[TomlLibTarget]>,
@@ -390,7 +395,7 @@ fn normalize(lib: Option<&[TomlLibTarget]>,
 
     fn target_profiles(target: &TomlTarget,
                        dep: Option<TestDep>) -> Vec<Profile> {
-        let mut ret = vec!(Profile::default_dev(), Profile::default_release());
+        let mut ret = vec![Profile::default_dev(), Profile::default_release()];
 
         match target.test {
             Some(true) | None => ret.push(Profile::default_test()),
@@ -402,6 +407,10 @@ fn normalize(lib: Option<&[TomlLibTarget]>,
             _ => {}
         }
 
+        if target.plugin == Some(true) {
+            ret = ret.move_iter().map(|p| p.plugin(true)).collect();
+        }
+
         ret
     }
 
@@ -411,7 +420,9 @@ fn normalize(lib: Option<&[TomlLibTarget]>,
         let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name));
         let crate_types = l.crate_type.clone().and_then(|kinds| {
             LibKind::from_strs(kinds).ok()
-        }).unwrap_or_else(|| vec!(Lib));
+        }).unwrap_or_else(|| {
+            vec![if l.plugin == Some(true) {Dylib} else {Lib}]
+        });
 
         for profile in target_profiles(l, Some(dep)).iter() {
             dst.push(Target::lib_target(l.name.as_slice(), crate_types.clone(),